jQuery(function ($, undefined) {
    var _tsObj = {
        cssHeader: "header",
        cssNoSort: "noSort",
        cssAsc: "asc",
        cssDesc: "desc",
        sortInitialOrder: "asc",
        sortForce: null,
        headers: {},
        detailList: {},
        widthFixed: false,
        cancelSelection: true,
        sortList: [],
        headerList: [],
        columnList: [],
        dateFormat: "us",
        decimal: '/\.|\,/g',
        selectorHeaders: 'thead th',
        // 回调函数，需要覆盖
        sort: function () {
        }
    },
    _internal = {
        tsObj: function (opts) {
            $.extend(true, _tsObj, opts);
        }
    },
    _tablesorter = {
        construct: function (settings, fullObj) {
            return this.each(function () {
                // if no thead or tbody quit.
                if (!this.tHead)
                    return;
                // declare
                var $this, $document, $headers, cache, config, shiftDown = 0,
                        sortOrder;
                this.config = {};
                config = $.extend(this.config, _tsObj, settings);
                $this = $(this);

                $headers = _tablesorter.buildHeaders(this);

                if (config.sortList.length > 0) {
                    var sortCSS = [config.cssDesc, config.cssAsc, config.cssNoSort];
                    _tablesorter.setHeadersCss($this[0], $headers, config.sortList, sortCSS);
                }

                $headers.click(
                        function (e) {
                            var totalRows = ((config.detailList)[0].tBodies[0] && (config.detailList)[0].tBodies[0].rows.length) || 0;
                            // 判断是否有数据行 以及 是否有排序列
                            if ((this.sortDisabled === 0) && totalRows > 0) {
                                // store exp, for speed
                                var $cell = $(this);
                                // get current column index
                                var i = this.column;
                                // flush the sort list
                                var order = 0;
                                var orderBy = "";
                                var _index = 0;
                                $.each(config.sortList, function (index) {
                                    if (config.sortList[index][0] === i) {
                                        order = config.sortList[index][1];
                                        switch (order) {
                                            case 0:
                                                order = 1;
                                                _index = index;
                                                orderBy = "ORDER BY " + config.columnList[index][1] + " ASC";
                                                break;
                                            case 1:
                                                order = 0;
                                                _index = index;
                                                orderBy = "ORDER BY " + config.columnList[index][1] + " DESC";
                                                break;
                                            case 2:
                                                order = 0;
                                                _index = index;
                                                orderBy = "ORDER BY " + config.columnList[index][1] + " DESC";
                                                break;
                                        }
                                        config.sortList[index][1] = order;
                                    } else
                                        config.sortList[index][1] = 2;
                                });

                                setTimeout(function () {
                                    $("th.sort__column").removeClass("asc").removeClass("desc");   // 目的为了使两个分开的表头保持一致的排序
                                    // set css for headers
                                    _tablesorter.setHeadersCss($this[0], $headers, config.sortList, sortCSS);
                                }, 1);

                                config.sort(orderBy, _index);

                                // stop normal event by returning false
                                return false;
                            }
                        }).mousedown(function () { // cancel selection
                    if (config.cancelSelection) {
                        this.onselectstart = function () {
                            return false;
                        };
                        return false;
                    }
                }
                );
            });
        },
        buildHeaders: function (table) {
            $("th.sort__column").removeClass("asc").removeClass("desc");   // 目的为了使两个分开的表头保持一致的排序
            
            var header_index = _tablesorter.computeTableHeaderCellIndexes(table);

            $tableHeaders = $(table.config.selectorHeaders, table).each(function (index) {
                this.column = header_index[this.parentNode.rowIndex + "-" + this.cellIndex];
                this.order = _tablesorter.formatSortingOrder(table.config.sortInitialOrder);

                //$(this).addClass(table.config.cssHeader);

                if (_tablesorter.checkHeaderOptions(table, index)) {
                    this.sortDisabled = 0;
                } else {
                    this.sortDisabled = 1;
                }
                if (_tablesorter.checkHeaderOptionsSortingLocked(table, index))
                    this.order = this.lockedOrder = _tablesorter.checkHeaderOptionsSortingLocked(table, index);

                if (this.sortDisabled === 0) {
                    var $th = $(this).addClass(table.config.cssHeader).addClass(table.config.cssNoSort);
                }

                // add cell to headerList
                table.config.headerList[index] = this;
            });

            return $tableHeaders;
        },
        computeTableHeaderCellIndexes: function (table) {
            var matrix = [];
            var lookup = {};
            var thead = table.getElementsByTagName('THEAD')[0];
            var trs = thead.getElementsByTagName('TR');

            for (var i = 0; i < trs.length; i++) {
                var cells = trs[i].cells;
                for (var j = 0; j < cells.length; j++) {
                    var c = cells[j];

                    var rowIndex = c.parentNode.rowIndex;
                    var cellId = rowIndex + "-" + c.cellIndex;
                    var rowSpan = c.rowSpan || 1;
                    var colSpan = c.colSpan || 1;
                    var firstAvailCol;
                    if (typeof (matrix[rowIndex]) === "undefined") {
                        matrix[rowIndex] = [];
                    }
                    // Find first available column in the first row
                    for (var k = 0; k < matrix[rowIndex].length + 1; k++) {
                        if (typeof (matrix[rowIndex][k]) === "undefined") {
                            firstAvailCol = k;
                            break;
                        }
                    }
                    lookup[cellId] = firstAvailCol;
                    for (var k = rowIndex; k < rowIndex + rowSpan; k++) {
                        if (typeof (matrix[k]) === "undefined") {
                            matrix[k] = [];
                        }
                        var matrixrow = matrix[k];
                        for (var l = firstAvailCol; l < firstAvailCol + colSpan; l++) {
                            matrixrow[l] = "x";
                        }
                    }
                }
            }
            return lookup;
        },
        formatSortingOrder: function (v) {
            if (typeof (v) !== "Number") {
                return (v.toLowerCase() === "desc") ? 1 : 0;
            } else {
                return (v === 1) ? 1 : 0;
            }
        },
        setHeadersCss: function (table, $headers, list, css) {
            // remove all header information
            $headers.removeClass(css[0]).removeClass(css[1]);//.addClass(css[2]);

            var h = [];
            $headers.each(function (offset) {
                if (this.sortDisabled === 0) {
                    h[this.column] = $(this);
                }
            });

            var l = list.length;
            for (var i = 0; i < l; i++) {
                h[list[i][0]].addClass(css[list[i][1]]);
            }
        },
        checkHeaderOptions: function (table, i) {
            if ((table.config.headers[i]) && (table.config.headers[i].sorter === false)) {
                return true;
            }

            return false;
        },
        checkHeaderOptionsSortingLocked: function (table, i) {
            if ((table.config.headers[i]) && (table.config.headers[i].lockedOrder)) {
                return table.config.headers[i].lockedOrder;
            }
            return false;
        },
        isValueInArray: function (v, a) {
            var l = a.length;
            for (var i = 0; i < l; i++) {
                if (a[i][0] === v) {
                    return true;
                }
            }
            return false;
        }
    };
    // Add jQuery call fucntions
    $.fn.extend({
        wxTableSorter: _tablesorter.construct
    });
    // Add global jQuery functions
    $.extend({
        tsObj: _internal.tsObj
    });
});